/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.panomedic.utils;


import com.panomedic.*;
import com.panomedic.colors.ColorConstants;
import com.panomedic.colors.Pixel;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.util.Arrays;
import java.util.prefs.Preferences;
/**
 *
 * @author Yare
 */
public class Utils {

     /** Return the dimensions for the image when scaled to fit to the given
     * limits. If the image is smaller than limits, it is not scaled.
     */
    public static Dimension getScaledSize(Dimension limits, int w, int h) {
        double wr = (double)w / limits.width;
        double hr = (double)h / limits.height;
        double scale = Math.max(wr,hr);
        scale = Math.max(scale, 1);
        return new Dimension((int)(w/scale), (int)(h/scale));
    }
    
    public static String getImageName(String path) {
        if (path == null)
            return "";
        else {
            File file = new File(path);
            return file.getName();
        }
    }
    
    
    /**
     * Cuts the values of pixel which exceed 255
     * @param px original pixel
     * @return new normalized psixel
     */
    public static int[] cutPixelOverlap(int[] px) {
        int[] px2 = new int[]{0,0,0,0};
        for( int i = 0; i < px.length; i++){
            if (px[i] > 255)
                px2[i] = 255;
            else if (px[i] < 0)
                px2[i] = 0;
            else px2[i] = px[i];
        }
        return px2;
    }
    
    /**
     * Finds out if the given pixel is opaque (alpha = 255)
     * @param px
     * @return true for 4 comp pixels, where comp[3] == 255
     * otherwise false
     */
    public static boolean isPixelOpaque( int[] px )  {
        if ( px.length == 4 )
            if ( px[3] == 255 )
                return true;
        return false;
    }
    
    public static double getLumFromRGB( int [] px ) {
        if (px.length < 3)
            return 0;
        else 
            return 0.299 * px[0] + 0.587 * px[1] + 0.114 * px[2];
    }

    public static double[] getPixelValues(int[] px, int csType) {
        if (px.length == 0) return null;
        Preferences prefs = Preferences.userRoot().node(Constants.defNodePath);
        
        Pixel px2 = Pixel.getPixel(csType, px);
        double[] array = px2.getComp();
        return array;
    }
    
    /**
     * Gets a pixel value(luminiscence) from px on the ColorSpace basis
     * @param px
     * @param csType
     * @return
     */
    
    public static double getPixelValue(int[] px, int csType) {
        if (px.length == 0) return -1;
        Preferences prefs = Preferences.userRoot().node(Constants.defNodePath);
        
        Pixel px2 = Pixel.getPixel(csType, px);
        double result = 0;
        switch (csType){
            case(ColorConstants.RGB):  result = 0.299*px2.getComp()[0] + 0.587*px2.getComp()[1] + 0.114*px2.getComp()[2];
                        break;
            case(ColorConstants.HSV):  result = px2.getComp()[2];
                        break;
            case(ColorConstants.Yxy):  result = px2.getComp()[0];
                        break;
            case(ColorConstants.Lab):  result = px2.getComp()[0];
                        break;
            case(ColorConstants.LCh):  result = px2.getComp()[0];
                        break;
            case(ColorConstants.Luv):  result = px2.getComp()[0];
                        break;
            default:    result = 0;
                        break;
        }
//        double result = px2.getComp()[0];
        return result;
    }
    
    
    public static BufferedImage cloneImage (BufferedImage img) {
        //bi is always ARGB !!
        BufferedImage newimg = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
        newimg.setData(img.getData());
        
        return newimg;
    }
    public static BufferedImage getCompatibleChildImage (BufferedImage img, int parentX, int parentY, int width, int height) {
        //bi is always ARGB !!
        
        BufferedImage newimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Raster r = img.getRaster().createChild(parentX, parentY, width, height, 0, 0, null);
        newimg.setData(r);
        
        return newimg;
    }
    
    public static boolean[] getCompProc(int value) {
        boolean[] result = new boolean[3];
        result[0] = ((value & 4) == 4) ?  true : false;
        result[1] = ((value & 2) == 2) ?  true : false;
        result[2] = ((value & 1) == 1) ?  true : false;
        return result;
    }
    public static int getCompProc(boolean[] value) {
        int result = 0;
        if (value[2]) result += 1;
        if (value[1]) result += 2;
        if (value[0]) result += 4;
        return result;
    }
    
    public static double[] addArray( double[] a1, double[] a2) {
        for (int i = 0; i < a1.length; i++) {
            a1[i] += a2[i];
        }
        return a1;
    }
    public static double[] subtractArray( double[] a1, double[] a2) {
        for (int i = 0; i < a1.length; i++) {
            a1[i] -= a2[i];
        }
        return a1;
    }
    /**
     * Returns array. which is created form two given by following operation :<br>
     * result = a1 - a2
     * @param a1
     * @param a2
     * @return
     */
    public static double[] subtractArrays( double[] a1, double[] a2) {
        double[] result = new double[3];
        for (int i = 0; i < a1.length; i++) {
            result[i] = a1[i] - a2[i];
        }
        return result;
    }
    
    public static double[] divideArray( double[] a1, double[] a2) {
        for (int i = 0; i < a1.length; i++) {
            a1[i] /= a2[i];
        }
        return a1;
    }
    public static double[] divideArray1( double[] a1, int a2) {
        for (int i = 0; i < a1.length; i++) {
            a1[i] /= a2;
        }
        return a1;
    }
    public static double[] divideArrays1( double[] a1, int a2) {
        double[] result = new double[3];
        for (int i = 0; i < a1.length; i++) {
            result[i] = a1[i] / a2;
        }
        return result;
    }
    
    public static double[] powerArray( double[] a2, double exponent) {
        double[] a1 = new double[3]; 
        for (int i = 0; i < a1.length; i++) {
            a1[i] = Math.pow(a2[i], exponent);
        }
        return a1;
    }
    public static double[] sqrtArray( double[] a1 ) {
        double[] result = new double[3];
        for (int i = 0; i < a1.length; i++) {
            result[i] = Math.sqrt(a1[i]);
        }
        return result;
    }
    public static double[] setArray0( double[] a ){
        for (int i = 0; i < a.length; i++) {
            a[i] = 0;
        }
        return a;
    }
    
    public static void main(String[] args) {
        double[] a1 = new double[]{4,5,6}; 
        double[] a2 = new double[]{1,2,3}; 
        System.out.println(Arrays.toString(addArray(a1,a2)));
        System.out.println(Arrays.toString(a1));
        System.out.println(Arrays.toString(a2));
    }
//    public static void main(String[] args) {
//        int x = 7;
//        x = getCompProc(getCompProc(x));
//        System.out.println(x);
//    }
    
}
